using System.Text.Json;

namespace exchangeApp
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            AsyncLoadCurrency().ConfigureAwait(false);
        }

        bool updateNow = false;
        public async Task UpdateCounter(int time)
        {
            int c = time / 1000;
            updateNow = false;
            while (c > 0)
            {
                c--;
                Update_label.Text = "Update in " + c.ToString();
                await Task.Delay(1000);
                if (updateNow)
                    break;
            }
            Update_label.Text = "Updating...";
        }

        private async Task AsyncLoadCurrency()
        {
            try
            {
                string[] urlsUSD =
                {
                    "https://api.coinbase.com/v2/prices/BTC-USD/spot",
                    "https://api.coinbase.com/v2/prices/ETH-USD/spot",
                    "https://api.coingecko.com/api/v3/coins/the-open-network",
                    "https://api.coinbase.com/v2/prices/SOL-USD/spot",
                    "https://www.floatrates.com/daily/usd.json",
                    "https://www.floatrates.com/daily/eur.json"
                };

                string[] urlsRUB =
                {
                    "https://api.coinbase.com/v2/prices/BTC-RUB/spot",
                    "https://api.coinbase.com/v2/prices/ETH-RUB/spot",
                    "https://api.coingecko.com/api/v3/coins/the-open-network",
                    "https://api.coinbase.com/v2/prices/SOL-RUB/spot"
                };

                int time = 600000;
                //int time = 20000;

                while (true)
                {
                    await LoadCurrency(urlsUSD, "usd");
                    await LoadCurrency(urlsRUB, "rub");
                    await UpdateCounter(time);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async Task LoadCurrency(string[] urls, string currency)
        {
            using (var client = new HttpClient())
            {
                await Parallel.ForEachAsync(Enumerable.Range(0, urls.Length), async (i, CancellationToken) =>
                {
                    if (i == 2)
                    {
                        var response = await client.GetStringAsync(urls[i]);
                        var jsonDoc = JsonDocument.Parse(response);
                        double rate = 0;
                        switch (currency)
                        {
                            case "usd":
                                rate = jsonDoc.RootElement
                                    .GetProperty("market_data")
                                    .GetProperty("current_price")
                                    .GetProperty("usd")
                                    .GetDouble();
                                break;
                            case "rub":
                                rate = jsonDoc.RootElement
                                    .GetProperty("market_data")
                                    .GetProperty("current_price")
                                    .GetProperty("rub")
                                    .GetDouble();
                                break;
                        }
                        double price = Convert.ToDouble(rate.ToString());

                        string formattedRate = price.ToString("#,0.00");

                        switch (currency)
                        {
                            case "usd":
                                await GetCurrency(formattedRate, i);
                                break;
                            case "rub":
                                await GetCurrencyRUB(formattedRate, i);
                                break;
                        }
                    }
                    else if (i == 4 || i == 5)
                    {
                        var response = await client.GetStringAsync(urls[i]);
                        var jsonDoc = JsonDocument.Parse(response);
                        var rate = jsonDoc.RootElement
                            .GetProperty("rub")
                            .GetProperty("rate");

                        double price = Convert.ToDouble(rate.ToString());

                        string formattedRate = price.ToString("#,0.00");

                        switch (currency)
                        {
                            case "usd":
                                await GetCurrency(formattedRate, i);
                                break;
                            case "rub":
                                await GetCurrencyRUB(formattedRate, i);
                                break;
                        }
                    }
                    else
                    {
                        var response = await client.GetStringAsync(urls[i]);
                        var jsonDoc = JsonDocument.Parse(response);
                        var rate = jsonDoc.RootElement
                            .GetProperty("data")
                            .GetProperty("amount");

                        double price = Convert.ToDouble(rate.ToString());

                        string formattedRate = price.ToString("#,0");

                        switch (currency)
                        {
                            case "usd":
                                await GetCurrency(formattedRate, i);
                                break;
                            case "rub":
                                await GetCurrencyRUB(formattedRate, i);
                                break;
                        }
                    }
                });
            }
        }

        public async Task GetCurrency(string price, int i)
        {
            await Task.Delay(1);
            switch (i)
            {
                case 0:
                    Bitcoin_Price.Text = "$ " + price;
                    break;
                case 1:
                    Ethereum_Price.Text = "$ " + price;
                    break;
                case 2:
                    Ton_Price.Text = "$ " + price;
                    break;
                case 3:
                    Solana_Price.Text = "$ " + price;
                    break;
                case 4:
                    USD_Price.Text = "RUB " + price;
                    break;
                case 5:
                    EUR_Price.Text = "RUB " + price;
                    break;
            }
        }

        public async Task GetCurrencyRUB(string price, int i)
        {
            await Task.Delay(1);
            switch (i)
            {
                case 0:
                    Bitcoin_rub_Price.Text = "RUB " + price;
                    break;
                case 1:
                    Ethereum_rub_Price.Text = "RUB " + price;
                    break;
                case 2:
                    Ton_rub_Price.Text = "RUB " + price;
                    break;
                case 3:
                    Solana_rub_Price.Text = "RUB " + price;
                    break;
            }
        }

        private void Update_button_Click(object sender, EventArgs e)
        {
            updateNow = true;
        }
    }
}
